package com.st.util;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @version V 1.0
 * @auther ROG
 * @date 2024/10/24
 * @project_name back
 * @description
 */
public class WXPayUtil {
    // 生成随机字符串
    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    // 生成签名
    public static String generateSignature(Map<String, String> data, String key) throws Exception {
        // StringBuilder sb = new StringBuilder();
        // for (Map.Entry<String, String> entry : data.entrySet()) {
        //     if (!"sign".equals(entry.getKey()) && entry.getValue() != null && entry.getValue().length() > 0) {
        //         sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        //     }
        // }
        // sb.append("key=").append(key);
        // return md5(sb.toString()).toUpperCase();

        StringBuilder sb = new StringBuilder();
        data.entrySet().stream()
                .filter(entry -> entry.getValue() != null && entry.getValue().length() > 0)
                .sorted(Map.Entry.comparingByKey())
                .forEach(entry -> sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&"));
        sb.append("key=").append(key);
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(sb.toString().getBytes("UTF-8"));
        StringBuilder hexString = new StringBuilder();
        for (byte b : array) {
            hexString.append(Integer.toHexString((b & 0xFF) | 0x100).substring(1, 3));
        }
        return hexString.toString().toUpperCase();
    }

    private static String md5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString();
    }

    // 将 Map 转换为 XML
    public static String mapToXml(Map<String, String> data) throws Exception {
        StringBuilder xml = new StringBuilder();
        xml.append("<xml>");
        for (Map.Entry<String, String> entry : data.entrySet()) {
            xml.append("<").append(entry.getKey()).append(">")
                    .append(entry.getValue()).append("</").append(entry.getKey()).append(">");
        }
        xml.append("</xml>");
        return xml.toString();
    }

    // 将 XML 转换为 Map
    public static Map<String, String> xmlToMap(String xmlStr) throws Exception {
        Map<String, String> data = new HashMap<>();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setExpandEntityReferences(false);
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new java.io.ByteArrayInputStream(xmlStr.getBytes("UTF-8")));
        NodeList nodeList = doc.getDocumentElement().getChildNodes();
        for (int idx = 0; idx < nodeList.getLength(); idx++) {
            Node node = nodeList.item(idx);
            data.put(node.getNodeName(), node.getTextContent());
        }
        return data;
    }

    public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
        String sign = data.get("sign");
        // 重新生成签名
        String generatedSign = generateSignature(data, key);
        return sign != null && sign.equals(generatedSign);
    }
}
